
import 'dart:async';
import 'dart:io';

import 'package:flutter/services.dart';
import 'path_provider.dart';

class PathProviderEx {

  static const MethodChannel _methodChannel = MethodChannel('com.jacky/path_provider');

  bool get isOhos => Platform.operatingSystem == 'ohos';

  Future<String?> getTemporaryPath() {
    return _methodChannel.invokeMethod<String>('getTemporaryDirectory');
  }

  Future<String?> getApplicationSupportPath() {
    return _methodChannel.invokeMethod<String>('getApplicationSupportDirectory');
  }

  Future<String?> getLibraryPath([String name = '']) {
    return _methodChannel.invokeMethod<String>('getLibraryDirectory', {'name' : name});
  }

  Future<String?> getApplicationDocumentsPath() {
    return _methodChannel.invokeMethod<String>('getApplicationDocumentsDirectory');
  }

  Future<String?> getExternalStoragePath() {
    if (Platform.isAndroid || isOhos) {
      return _methodChannel.invokeMethod<String>('getStorageDirectory');
    }
    throw UnsupportedError('Functionality available on Android or HarmonyOS');
  }

  Future<List<String>?> getExternalCachePaths() {
    if (Platform.isAndroid) {
        return _methodChannel.invokeListMethod<String>('getExternalCacheDirectories');
    }
    throw UnsupportedError('Functionality only available on Android');
  }

  Future<List<String>?> getExternalStoragePaths({
    StorageDirectory? type,
  }) async {
    if (Platform.isAndroid || isOhos) {
      return _methodChannel.invokeListMethod<String>('getExternalStorageDirectories', <String, dynamic>{'type': type?.index});
    }
    throw UnsupportedError('Functionality available on Android or HarmonyOS');
  }

  Future<String?> getDownloadsPath() {
    return _methodChannel.invokeMethod<String>('getDownloadsDirectory');
  }

  Future<String?> getExternalSdcardPath() {
    if (Platform.isAndroid) {
      return _methodChannel.invokeMethod<String>('getExternalSdcardPath');
    }
    throw UnsupportedError('Functionality only available on Android');
  }

  Future<int> getVideoDuration(String videoPath) {
    return _methodChannel.invokeMethod<int>('getVideoDuration', {"path" : videoPath}).then((value) => value??0);
  }

  Future<int> getAvailableSize() {
    return _methodChannel.invokeMethod<int>('getAvailableSize').then((value) => value??0);
  }

  Future<int> getAvailableStoragePercent() {
    return _methodChannel.invokeMethod<int>('getAvailableStoragePercent').then((value) => value??0);
  }

  goAppleStore(String iosAppStoreId) {
    if (Platform.isIOS) {
      if (iosAppStoreId.isEmpty) {
        print("InstallApp, but ios appStoreId is empty");
      } else {
        _methodChannel.invokeMethod("installApp", "itms-apps://itunes.apple.com/app/id$iosAppStoreId");
      }
    } else {
      throw UnsupportedError('Functionality only available on iOS/macOS');
    }
  }

  installApk(String path) {
    if (Platform.isAndroid) {
      if (path.isEmpty) {
        print("InstallApp, but apk path is empty");
      } else {
        _methodChannel.invokeMethod("installApp", path);
      }
    } else {
      throw UnsupportedError('Functionality only available on Android');
    }
  }

  Future<int> environmentCheck() {
    return _methodChannel.invokeMethod("environmentCheck").then((value) => value??0);
  }

  openAdbUI() {
    if (Platform.isAndroid) {
      _methodChannel.invokeMethod("openAdbUI");
    }
  }

  Future<String?> nativeImageCachePath(String name, String type, bool useCache) {
    if (Platform.isAndroid) {
      String s = name.split('.')[0];
      return _methodChannel.invokeMethod("nativeImageCachePath", {'name':s, 'type': type, 'useCache':useCache});
    } else {
      print("loadNativeImage= Functionality only available on Android");
      return Future.value(null);
      // throw UnsupportedError('Functionality only available on Android');
    }
  }

  Future<Map> getExifInfoFromMedia(String path) {
    return _methodChannel.invokeMethod("exifInfo", path).then((value) => value??{});
  }

  Future<bool> thumbnailImage(
      String path, String thumbPath, int width, int height) async {
    return _methodChannel.invokeMethod("thumbnailImage", {
      'path': path,
      'thumbPath': thumbPath,
      'width': width,
      'height': height
    }).then((value) => value ?? false);
  }

  mediaScanner(String path) {
    _methodChannel.invokeMethod("mediaScanner", path);
  }

  Future moveFile(String path) {
    return _methodChannel.invokeMethod("moveFile", path);
  }
}
